package flare.data
{
  import flare.data.converters.Converters;
  import flare.data.converters.IDataConverter;

  import flash.events.Event;
  import flash.net.URLLoader;
  import flash.net.URLLoaderDataFormat;
  import flash.net.URLRequest;

  /**
   * A data source provides access to remote data on the Internet.
   * A DataSource requires a URL for retrieving a data file, and a format
   * string representing the data format. The currently supported formats are
   * "tab" (Tab-Delimited Text) and "json" (JavaScript Object Notation).
   * Additionally, a DataSource can be given a schema object describing the
   * data fields and their types (int, Number, Date, String, etc). If no
   * schema is provided, the data converter for the particular format will
   * attempt to infer the data types directly from the data itself.
   * 
   * <p>Once a DataSource has been created, use the <tt>load</tt> method to
   * initiate data loading. This method returns a <tt>URLLoader</tt> 
   * instance. Add a listener to the URLLoader's COMPLETE event to be
   * notified when loading and parsing has been completed. When a COMPLETE
   * event is issued, the URLLoader's <tt>data</tt> property will contain the
   * loaded and parsed data set.</p>
   */
  public class DataSource
  {
    private var _url:String;
    private var _format:String;
    private var _schema:DataSchema;

    /** The URL of the remote data set. */
    public function get url():String
    {
      return _url;
    }

    public function set url(u:String):void
    {
      _url = u;
    }
    /** The format of the remote data set (e.g., "tab" or "json"). */
    public function get format():String
    {
      return _format;
    }
    /** A schema describing the attributes of the data set. */
    public function get schema():DataSchema
    {
      return _schema;
    }

    /**
     * Creates a new DataSource.
     * @param url the URL of the remote data set
     * @param format the format of the remote data set (e.g., "tab" or
     *  "json")
     * @param schema an optional schema describing the attibutes of the
     *  data set
     */
    public function DataSource(url:String, format:String, schema:DataSchema = null)
    {
      _url = url;
      _format = format;
      _schema = schema;
    }

    /**
     * Initiates loading of the data set. When the load completes, a data
     * converter instance is used to convert the retrieved data set into
     * ActionScript objects. The parsed data is then available through the
     * <code>data</code> property of the returned <code>URLLoader</code>.
     * @return a URLLoader instance responsible for loading the data set.
     *  Add an event listener for the <code>COMPLETE</code> event to be
     *  notified when data loading has completed.
     */
    public function load():URLLoader
    {
      var loader:URLLoader = new URLLoader();
      loader.dataFormat = URLLoaderDataFormat.BINARY;
      loader.addEventListener(Event.COMPLETE, function(evt:Event):void
      {
        var conv:IDataConverter = Converters.lookup(_format);
        loader.data = conv.read(loader.data, _schema);
      });
      loader.load(new URLRequest(_url));
      return loader;
    }

  /* TODO later -- support streaming data
  public function stream():URLStream
  {
    
  }
  */

  } // end of class DataSource
}